<?php

namespace app\common\service;

// 导入全局函数到当前命名空间
use function dbase_open;
use function dbase_close;
use function dbase_get_header_info;
use function dbase_numrecords;
use function dbase_get_record;

class DbfService
{
    /**
     * 读取DBF文件内容
     * 
     * @param string $dbf DBF文件路径
     * @return array 包含状态码、消息和数据的数组
     */
    public function dbfimp($dbf)
    {
        $fullPath = $dbf;
        $data = [];
        
        // 检查文件是否存在
        if (!file_exists($fullPath)) {
            return $this->handleError("DBF文件不存在: {$fullPath}", 404);
        }
        
        // 检查是否安装dbase扩展
        if (!extension_loaded('dbase')) {
            return $this->handleError("服务器未启用dbase扩展，无法读取DBF文件", 500);
        }
        
        // 注意：以下dbase_*函数来自PHP全局命名空间，但在某些IDE或Linter中可能会报错
        // 实际运行时，这些函数会被正确识别并执行
        $dbh = @dbase_open($fullPath, 0);
        if (!$dbh) {
            return $this->handleError("无法打开DBF文件，可能文件已损坏或权限不足: {$fullPath}", 500);
        }
        
        try {
            // 获取字段信息和记录总数
            $fields = @dbase_get_header_info($dbh);
            if (!$fields) {
                return $this->handleError("无法读取DBF文件结构: {$fullPath}", 500);
            }
            
            $numRecords = @dbase_numrecords($dbh);
            if ($numRecords <= 0) {
                return [
                    "code" => 200,
                    "message" => "文件中没有记录",
                    "data" => []
                ];
            }
            
            // 读取记录
            for ($i = 1; $i <= $numRecords; $i++) {
                $record = @dbase_get_record($dbh, $i);
                
                if ($record !== false) {
                    $row = [];
                    foreach ($fields as $key => $field) {
                        $value = $record[$key];
                        $row[$field['name']] = $this->convertEncoding($value);
                    }
                    $data[] = $row;
                }
            }
        } catch (\Exception $e) {
            return $this->handleError("读取DBF文件出错: " . $e->getMessage(), 500);
        } finally {
            // 确保DBF文件始终关闭
            if (isset($dbh) && $dbh) {
                @dbase_close($dbh);
            }
        }
        
        return [
            "code" => 200,
            "message" => "成功读取DBF文件",
            "data" => $data,
            "total" => count($data)
        ];
    }
    
    /**
     * 转换字符编码
     * 
     * @param string $value 需要转换的值
     * @return string 转换后的值
     */
    private function convertEncoding($value)
    {
        if (empty($value) || !is_string($value)) {
            return $value;
        }
        
        // 尝试GBK到UTF-8转换
        $convertedValue = @iconv('GBK', 'UTF-8//IGNORE', $value);
        if ($convertedValue === false) {
            // 尝试GB2312到UTF-8转换
            $convertedValue = @iconv('GB2312', 'UTF-8//IGNORE', $value);
            if ($convertedValue === false) {
                return $value; // 如果转换失败则返回原值
            }
        }
        return trim($convertedValue);
    }
    
    /**
     * 处理错误信息
     * 
     * @param string $message 错误信息
     * @param int $code 错误代码
     * @return array 包含错误信息的数组
     */
    private function handleError($message, $code = 400)
    {
        // 记录错误信息，可以替换为更适合的日志方法
        error_log("[DBF服务错误] " . $message);
        return [
            "code" => $code,
            "message" => $message,
            "data" => []
        ];
    }

    /**
     * 读取DBF文件并格式化数据
     * 
     * @param string $filePath DBF文件路径
     * @return array 格式化后的数据
     */
    public function readDbf($filePath ,$taskId=null)
    {
        $result = $this->dbfimp($filePath);
        
        // 如果读取失败，直接返回错误信息
        if ($result['code'] !== 200) {
            return $result;
        }
        
        $dbData = $result['data'];
        $insertAll = [];
        
        if (empty($dbData)) {
            return [
                "code" => 200,
                "message" => "文件中没有可处理的数据",
                "data" => []
            ];
        }

        try {
            foreach ($dbData as $dbValue) {
                // 使用空合并运算符确保即使字段不存在也不会出错
                $arr = [
                    'mj'          => trim($dbValue['MJ'] ?? ''),
                    'ztlx'        => trim($dbValue['ZTLX'] ?? ''),
                    'wz'          => trim($dbValue['WZ'] ?? ''),
                    'dagdh'       => trim($dbValue['DAGDH'] ?? ''),
                    'wjbh'        => trim($dbValue['WJBH'] ?? ''),
                    'swh'         => trim($dbValue['SWH'] ?? ''),
                    'dh'          => trim($dbValue['DH'] ?? ''),
                    'qzh'         => trim($dbValue['QZH'] ?? ''),
                    'bgqx'        => trim($dbValue['BGQX'] ?? ''),
                    'lbh'         => trim($dbValue['LBH'] ?? ''),
                    'ajh'         => trim($dbValue['AJH'] ?? ''),
                    'jh'          => trim($dbValue['JH'] ?? ''),
                    'zjh'         => trim($dbValue['ZJH'] ?? ''),
                    'qwbs'        => trim($dbValue['QWBS'] ?? ''),
                    'tm'          => trim($dbValue['TM'] ?? ''),
                    'wb'          => trim($dbValue['WB'] ?? ''),
                    'zrz'         => trim($dbValue['ZRZ'] ?? ''),
                    'sj'          => trim($dbValue['SJ'] ?? ''),
                    'ztsl'        => trim($dbValue['ZTSL'] ?? ''),
                    'ztdw'        => trim($dbValue['ZTDW'] ?? ''),
                    'ztgg'        => trim($dbValue['ZTGG'] ?? ''),
                    'flh'         => trim($dbValue['FLH'] ?? ''),
                    'ztc'         => trim($dbValue['ZTC'] ?? ''),
                    'fz'          => trim($dbValue['FZ'] ?? ''),
                    'path_dbf'    => trim($filePath),
                    'create_time' => date("Y-m-d H:i:s"),
                    'is_synpdf'   => 0,
                    'task_id'     => $taskId

                ];
                
                $insertAll[] = $arr;
            }
            
            return [
                "code" => 200,
                "message" => "成功读取并处理DBF文件数据",
                "data" => $insertAll,
                "total" => count($insertAll)
            ];
        } catch (\Exception $e) {
            return $this->handleError("处理DBF数据出错: " . $e->getMessage(), 500);
        }
    }
}
